package com.common.www.filter;

import com.alibaba.fastjson.JSON;
import com.common.www.bean.vo.UserVo;
import com.common.www.config.WebConfig;
import com.common.www.data.NetCode;
import com.common.www.service.auth.TokenService;
import com.common.www.service.auth.UserService;
import com.common.www.service.global.GlobalConfigService;
import com.common.www.utils.GlobalSessionUtils;
import com.common.www.utils.R;
import com.common.www.utils.TxtUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.ContentCachingRequestWrapper;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Component
public class HttpInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    TokenService tokenService;
    @Autowired
    UserService userService;
    @Autowired
    GlobalConfigService globalConfigService;

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {

        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");

        WkResponseWrapper responseWrapper = new WkResponseWrapper((HttpServletResponse) response);
        ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper((HttpServletRequest) request);

        String requestUri = requestWrapper.getRequestURI();
        String suffix = requestUri.substring(requestUri.lastIndexOf(".") + 1, requestUri.length());//提取后缀
        boolean htmlRequest = requestUri.contains(".html") || requestUri.contains(".htm");//是否是html请求
//        if (StringUtils.equals("pdf", suffix) || StringUtils.equals("PDF", suffix)) {
//            return true;
//        }
        String tokenHeader = request.getHeader(WebConfig.Token);

        if (TxtUtil.isEmpty(tokenHeader)) {//当没传token时尝试从session中去token
            HttpSession session = requestWrapper.getSession();
            Object user = session.getAttribute(WebConfig.ACCOUNT_KEY);
            if (user != null) {
                tokenHeader = user + "";
            }
        }

        if (TxtUtil.isEmpty(tokenHeader)) {//token为空直接报错
            return responseTokenError(responseWrapper, htmlRequest, requestUri, NetCode.CODE_TOKEN_INAVALILABLE);
        }

        try {

            UserVo user = userService.getUserVoFromRedis(tokenHeader);
            if (user == null) {
                //自动退出登录
                userService.exitLogin(tokenHeader);
                return responseTokenError(responseWrapper, htmlRequest, requestUri, NetCode.CODE_TOKEN_INAVALILABLE);
            } else if (user.getLocked()) {//用户被锁定
                return responseTokenError(responseWrapper, htmlRequest, requestUri, NetCode.CODE_AUTH_USER_LOCK);
            }
            if (user != null) {
                userService.updateRedisUserExpireTime(tokenHeader);
            }

//            过期了自动不可用,为了节约性能所以这里就不再次验证token 的可用性了
//            JwtUtils.TOKEN_STATUS token_status = JwtUtils.checkToken(tokenHeader);
//            if (token_status == JwtUtils.TOKEN_STATUS.EXPIRED) {//验证token
//                return responseTokenError(responseWrapper, htmlRequest, requestUri, NetCode.CODE_TOKEN_INAVALILABLE);
//            } else if (token_status == JwtUtils.TOKEN_STATUS.EXCEPTION) {
//                return responseTokenError(responseWrapper, htmlRequest, requestUri, NetCode.CODE_TOKEN_INAVALILABLE);
//            } else {//验证成功
////                System.out.println(System.currentTimeMillis() - start);
//                return true;
//            }

        } catch (Exception e) {
            return responseTokenError(responseWrapper, htmlRequest, requestUri, NetCode.CODE_TOKEN_INAVALILABLE);
        }

        return true;
    }

    /**
     * 错误码、是否验证不过时是否重定向html地址
     */
    private boolean responseTokenError(WkResponseWrapper responseWrapper, boolean htmlJump, String requestUri, NetCode code) {
        try {
            responseWrapper.setContentType("application/x-json;charset=UTF-8");
            if (htmlJump) {//如果是网页请求直接返回登陆页面
                GlobalSessionUtils.getSession().setAttribute(WebConfig.LastUrl, requestUri);
                responseWrapper.sendRedirect(globalConfigService.getProjectName() + "login/login.html");
                return true;
            } else {
                responseWrapper.setStatus(200);//设置成功返回
                responseWrapper.getWriter().write(JSON.toJSONString(R.returnCode(code)));
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

}